package com.gm.commonlib.module.image;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;

import androidx.fragment.app.Fragment;


import com.gm.commonlib.util.fileUtil.FileUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;


public class BitmapUtils {
    public static final String FKH_IMAGE_PATH = "/fkh_image/";

    public static boolean isBitmapAvailable(Bitmap bitmap) {
        return bitmap != null && !bitmap.isRecycled();
    }

    public static void recycleBitmap(Bitmap bitmap) {
        if (isBitmapAvailable(bitmap)) {
            bitmap.recycle();
            ;
        }
    }

    public static void recycle(Object object) {
        if (object instanceof Bitmap) {
            recycleBitmap((Bitmap) object);
        }
    }

    /**
     * 获取原始图片的角度（解决三星手机拍照后图片是横着的问题）
     *
     * @param path 图片的绝对路径
     * @return 原始图片的角度
     */
    public static int getBitmapDegree(String path) {
        int degree = 0;
        try {
            // 从指定路径下读取图片，并获取其EXIF信息
            ExifInterface exifInterface = new ExifInterface(path);
            // 获取图片的旋转信息
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            Log.e("jxf", "orientation" + orientation);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转图片，恢复到原始角度
     *
     * @param bitmap        被旋转后位图对象
     * @param pictureDegree 图片被旋转的角度
     * @return 如果处理过程中出现异常，返回原始位图，否则 返回修正后的位图
     */
    public static Bitmap rotate(Bitmap bitmap, int pictureDegree) {
        try {
            // 根据旋转角度，生成旋转矩阵
            Matrix matrix = new Matrix();
            matrix.postRotate(pictureDegree);
            return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (Exception e) {
            return bitmap;
        }
    }

    /*
     * 从相机获取
     */
    public static void camera(Activity activity, int requestCode, File folder, String fileName) {
        camera(activity, requestCode, new File(folder, fileName));
    }

    /*
     * 从相机获取
     */
    public static void camera(Activity activity, int requestCode, File tempFile) {
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        if (FileUtils.hasSdcard()) {
            Uri uri = Uri.fromFile(tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        }
        activity.startActivityForResult(intent, requestCode);
    }

    /*
     * 剪切图片
     */
    public static Uri cropPhoto(Activity activity, int requestCode, Uri uri) {
        return cropPhoto(activity, requestCode, uri, 200, 200);
    }

    /*
     * 剪切图片
     */
    public static Uri cropPhoto(Activity activity, int requestCode, Uri uri, int width, int height) {
        return crop(activity, requestCode, uri, width, height);
    }

    public static File lastCutFile() {
        return new File(Environment.getExternalStorageDirectory(), "FA0989CDA0");
    }

    /*
     * 剪切图片
     */
    public static Uri crop(Activity activity, int requestCode, Uri uri, int width, int height) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        // 裁剪框的比例，1：1
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // 裁剪后输出图片的尺寸大小
        intent.putExtra("outputX", width);
        intent.putExtra("outputY", height);

        intent.putExtra("outputFormat", "JPEG");// 图片格式
        intent.putExtra("noFaceDetection", true);// 取消人脸识别
        intent.putExtra("return-data", true);
        Uri uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");

        intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);

        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());

        activity.startActivityForResult(intent, requestCode);
        return uritempFile;
    }

    public static Uri crop(Fragment fragment, int requestCode, Uri uri, int width, int height, File targetFile) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        // 裁剪框的比例，1：1
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // 裁剪后输出图片的尺寸大小
        intent.putExtra("outputX", width);
        intent.putExtra("outputY", height);

        intent.putExtra("outputFormat", "JPEG");// 图片格式
        intent.putExtra("noFaceDetection", true);// 取消人脸识别
        intent.putExtra("return-data", true);

        Uri uritempFile = Uri.fromFile(targetFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());

        fragment.startActivityForResult(intent, requestCode);
        return uritempFile;
    }


    /**
     * 按照质量压缩图片
     *
     * @param bitmap
     * @param quality
     * @return
     */
    public static Bitmap compressBitMap(Bitmap bitmap, int quality) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();


        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);

        byte[] bytes = baos.toByteArray();
        bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        Log.i("fkh", "压缩后图片的大小" + (bitmap.getByteCount() / 1024 / 1024)

                + "M宽度为" + bitmap.getWidth() + "高度为" + bitmap.getHeight()

                + "bytes.length=  " + (bytes.length / 1024) + "KB"

                + "quality=" + quality);

        return bitmap;
    }



    private static Bitmap compress(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        Log.d("fkh", " compress size: " + bitmap.getByteCount() + " width: " + bitmap.getWidth() + " heigth:" + bitmap.getHeight()
                + "压缩后图片的大小" + (bitmap.getByteCount() / 1024)); // 输出图像数据
        return bitmap;
    }

    public static Bitmap compressImage(Bitmap image, int width, int heith) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%，把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        float hh = heith;
        float ww = width;
        //缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0) {
            be = 1;
        }
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        bitmap = compress(bitmap);//压缩好比例大小后再进行质量压缩
        Log.d("fkh", "compress size: " + bitmap.getByteCount() + " width: " + bitmap.getWidth() + " heigth:" + bitmap.getHeight()
                + "压缩后图片的大小" + (bitmap.getByteCount() / 1024)); // 输出图像数据
        return bitmap;
    }

    public void getBitMap(String imagePath) {
        // 设置参数

        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inJustDecodeBounds = true; // 只获取图片的大小信息，而不是将整张图片载入在内存中，避免内存溢出

        BitmapFactory.decodeFile(imagePath, options);

        int height = options.outHeight;

        int width = options.outWidth;

        int inSampleSize = 8; // 默认像素压缩比例，压缩为原图的1/2

        int minLen = Math.min(height, width); // 原图的最小边长

        if (minLen > 100) { // 如果原始图像的最小边长大于100dp（此处单位我认为是dp，而非px）

            float ratio = (float) minLen / 100.0f; // 计算像素压缩比例

            inSampleSize = (int) ratio;

        }
        options.inJustDecodeBounds = false; // 计算好压缩比例后，这次可以去加载原图了
        options.inSampleSize = inSampleSize; // 设置为刚才计算的压缩比例
        Bitmap bmp = BitmapFactory.decodeFile(imagePath, options); // 解码文件
        Log.d("fkh", "size: " + bmp.getByteCount() + " width: " + bmp.getWidth() + " heigth:" + bmp.getHeight()
                + "压缩后图片的大小" + (bmp.getByteCount() / 1024 / 1024)); // 输出图像数据


    }


}
